/**
 * N个矩形，for k in [1...N]，问任选K个矩形的并集的面积的期望是多少。
 * N在3E3
 * 
 * 离散化坐标，一共有9E6个格子，记录每个格子被覆盖的次数，
 * 这里要用二维树状数组维护差分数组，实现原数组上的区间修改单点查询
 * 
 * 然后将所有覆盖次数为i的面积累加起来，记作Si
 * 
 * for k in [1...N]:
 *     ans = 0
 *     for i in [1...N]:
 *         if N - i >= k: # 一共有C(N-i,K)种方法可以不选Si
 *             ans += Si * (C(N, K) - C(N - i, K))         
 *         else: # 说明任选k个，该面积必然被选中
 *             ans += C(N, k) * Si
 *     ans /= C(N, K)
 *     ans是k的答案，输出
 * 
 * 压线过，将cout的endl改成换行符就T了，应该有什么能优化的
 * 优化了一点，951ms
 */
#include <bits/stdc++.h>
using namespace std;
#include <bits/extc++.h>
using namespace __gnu_pbds;

using llt = long long;
using vi = vector<int>;
using vll = vector<llt>;

llt const MOD = 998244353LL;

llt qpow(llt a, llt n){
    a %= MOD;
    llt ret = 1;
    while(n){
        if(n & 1) ret = ret * a % MOD;
        a = a * a % MOD;
        n >>= 1;
    }
    return ret;
}

llt inv(llt a) {return qpow(a, MOD - 2LL);}

vector<vector<llt>> C;

struct FenwickTree2D{ // 二维树状数组

using value_type = int;
using vec_type = vector<value_type>;

int n, m;
vector<vec_type> c;

FenwickTree2D() = default;

static int lowbit(int x){return x & -x;}

void init(int nn, int mm){this->c.assign((this->n=nn) + 1, vec_type((this->m=mm) + 1, 0));}

void modify(int x, int y, value_type delta){
    for(int i=x;i<=this->n;i+=lowbit(i))for(int j=y;j<=this->m;j+=lowbit(j))this->c[i][j] += delta;
}

value_type query(int x, int y)const{
    value_type ans = 0;
    for(int i=x;i;i-=lowbit(i))for(int j=y;j;j-=lowbit(j)) ans += this->c[i][j];
    return ans;
}

value_type query(int xs, int xe, int ys, int ye)const{
    return query(xe, ye) + query(xs - 1, ys - 1) - query(xe, ys - 1) - query(xs - 1, ye);
}

};

struct Point{
    int x, y;
};

int N;
vector<pair<Point, Point>> Rect;
vi Wx, Wy;
int Mx, My;
FenwickTree2D Bt;

void work(){
    cin >> N;

    C.assign(N + 1, vll(N + 1, 0));
    C[0][0] = 1;
    for(int i=1;i<=N;++i){
        C[i][0] = C[i][i] = 1;
        for(int j=1;j<i;++j){
            C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
        }
    }

    Rect.assign(N, {});
    Wx.reserve(N + N + 1);
    Wy.reserve(N + N + 1);
    Wx.push_back(0);
    Wy.push_back(0);
    for(auto & p : Rect){
        cin >> p.first.x >> p.first.y >> p.second.x >> p.second.y;
        Wx.push_back(p.first.x);
        Wy.push_back(p.first.y);
        Wx.push_back(p.second.x);
        Wy.push_back(p.second.y);
    }
    
    sort(Wx.begin(), Wx.end());
    Wx.erase(unique(Wx.begin(), Wx.end()), Wx.end());
    sort(Wy.begin(), Wy.end());
    Wy.erase(unique(Wy.begin(), Wy.end()), Wy.end());

    Mx = Wx.size();
    My = Wy.size();

    Bt.init(Mx, My);
    for(int i=0;i<N;++i){
        int xmini = Rect[i].first.x;
        int ymini = Rect[i].first.y;
        int xmaxi = Rect[i].second.x;
        int ymaxi = Rect[i].second.y;
        
        int wxleft = lower_bound(Wx.begin(), Wx.end(), xmini) - Wx.begin();
        int wxright = lower_bound(Wx.begin(), Wx.end(), xmaxi) - Wx.begin();

        int wybot = lower_bound(Wy.begin(), Wy.end(), ymini) - Wy.begin();
        int wytop = lower_bound(Wy.begin(), Wy.end(), ymaxi) - Wy.begin();

        assert(wxright >= wxleft and wytop >= wybot);
        assert(1 <= wxleft and wxright <= Mx);
        assert(1 <= wybot and wytop <= My);

        Bt.modify(wxleft, wybot, 1);
        Bt.modify(wxleft, wytop, -1);
        Bt.modify(wxright, wybot, -1);
        Bt.modify(wxright, wytop, 1);
    }

    vector<llt> Map(N + 1, 0);
    for(int i=1;i<Mx-1;++i){
        llt xleft = Wx[i];
        llt xright = Wx[i + 1];
        for(int j=1;j<My-1;++j){
            llt ybot = Wy[j];
            llt ytop = Wy[j + 1];
            int c = Bt.query(1, i, 1, j);
            // cout << i << ", " << j << ": " << c << endl;
            if(c){
                Map[c] = (Map[c] + (ytop - ybot) * (xright - xleft) % MOD) % MOD;
            }
            
        }
    }

    for(int i=1;i<=N;++i){
        llt ans = 0;
        auto ni = inv(C[N][i]);

        for(int c=1;c<=N;++c){
            // int c = p.first;
            llt tmp = 0;
            llt w = Map[c];
            if(0 == w) continue;

            tmp = tmp + 1;
            if(N - c >= i){
                tmp = (tmp - (C[N - c][i] * ni % MOD)) % MOD;
                if(tmp < 0) tmp += MOD;
            }

            ans = (ans + tmp * w % MOD) % MOD;      
        }
        cout << ans << "\n";
        // cout << ans << endl;
    }
	return;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);	
    int nofkase = 1;
	// cin >> nofkase;
	while(nofkase--) work();
	return 0;
}